/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package wat.clientapp.remote;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import wat.ziszcommon.remote.ClassProvider;
import wat.ziszcommon.remote.CryptoUtils;
import wat.ziszcommon.remote.RemoteModuleFactory;

/**
 *
 * @author Marcin
 */
public class RemoteClassLoader extends ClassLoader {

    private ClassProvider classProvider;
    private String dirPath = "c:/clientapp/classes/";

    public RemoteClassLoader() {
        super();
        Object proxy = RemoteModuleFactory.getInstance().createProxy(ClassProvider.class);
        if (proxy instanceof ClassProvider) {
            classProvider = (ClassProvider) proxy;
        }
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        String path = name.replace('.', '/').concat(".class");
        //najpierw sprawdz czy klasa jest w lokalnym repozytorium
        try {
            File file = new File(dirPath + path);
            byte[] data = new byte[(int) file.length()];
            FileInputStream fis = new FileInputStream(file);
            if (fis.read(data) == data.length) {
                String md5 = classProvider.getMd5(name);
                if (CryptoUtils.md5(data).equals(md5)) {
                    //aktualna wersja klasy
                    return defineClass(name, data, 0, data.length);
                } else {
                    //nalezy pobrac nowa wersje klasy
                    return getClassFromServer(name);
                }
            }
        } catch (FileNotFoundException e) {
            //pobierz klase z serwera
            return getClassFromServer(name);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        throw new ClassNotFoundException(name);
    }

    private Class<?> getClassFromServer(String name) throws ClassNotFoundException {
        String path = name.replace('.', '/').concat(".class");
        String dirStr = path.substring(0, path.lastIndexOf('/'));
        try {
            byte[] data = classProvider.getClass(name);
            String md5 = classProvider.getMd5(name);
            if (CryptoUtils.md5(data).equals(md5)) {
                File dir = new File(dirPath + dirStr);
                dir.mkdirs();
                File file = new File(dirPath + path);
                file.createNewFile();
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(data);
                fos.close();
            }
            return defineClass(name, data, 0, data.length);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        throw new ClassNotFoundException(name);
    }
}
